/*
 * @Author: yangshangchao
 * @Date: 2025-01-13 09:18:39
 * @LastEditors: yangshangchao
 * @Description: 头部注释
 */
import { useState, useReducer } from 'react';

const initState = {
  count: -1,
};
type State = typeof initState;
// state参数接收的是设定的默认值
// 函数返回值是state的默认值
const initFn = (state: State) => {
  // 只在初始时执行一次
  // console.log('initFn', state);
  // return Math.abs(state.count); !!!错误，默认值是对象类型，必须返回符合State类型对象
  return { count: Math.abs(state.count) };
};

/**
 * @description: 处理函数，更新 state 的纯函数。通过dispatch触发才执行
 * @param {State} state 参数接收的是state的默认值
 * @param {object} action 参数接收的是dispatch传入的对象
 * @return {*} 返回新的state，数据类型看默认值
 */
const reducer = (state: State, action: { type: 'increment' | 'decrement' }) => {
  console.log(action, 'reducer');
  switch (action.type) {
    case 'increment':
      return { count: state.count + 1 };
    case 'decrement':
      return { count: state.count - 1 };
    default:
      return state;
  }
};

const initShopCar = [
  { name: '蓝莓(只)', price: 100, count: 1, id: 1, isEdit: false },
  { name: '草莓(只)', price: 200, count: 1, id: 2, isEdit: false },
  { name: '苹果(只)', price: 300, count: 1, id: 3, isEdit: false },
];
type ShopCar = typeof initShopCar;
interface Action {
  type: 'INCREMENT' | 'DECREMENT' | 'DELETE' | 'EDIT' | 'UPDATE_NAME' | 'BLUR';
  id: number;
  newName?: string;
}
const reducerShop = (data: ShopCar, action: Action) => {
  console.log(action, 'reducerShop');
  const target = data.find((item) => item.id === action.id)!; // 需要加!  给非空断言，否则target.count++ 报“target”可能为“未定义”。ts(18048)
  switch (action.type) {
    case 'INCREMENT':
      target.count++;
      return [...data];
    case 'DECREMENT':
      target.count--;
      return [...data];
    case 'DELETE':
      return data.filter((item) => item.id !== action.id);
    case 'EDIT':
      target.isEdit = true;
      return [...data];
    case 'UPDATE_NAME':
      target.name = action.newName!;
      return [...data];
    case 'BLUR':
      target.isEdit = false;
      return [...data];
    default:
      return data;
  }
};

function App() {
  const [count, setCount] = useState(0);
  // 第一个参数 处理函数，更新 state 的纯函数
  // 第二个参数 state 的初始值
  // 第三个参数（可选）state 的初始化函数（初始值的处理函数），state的默认值先取initFn的返回值，如无再取initState
  // state对应默认值initState
  const [state, dispatch] = useReducer(reducer, initState, initFn);
  const [data, dispatchData] = useReducer(reducerShop, initShopCar);

  return (
    <>
      <div>
        <h2>计数器案例：对比useState和useReducer</h2>
        <h3>useState</h3>
        <div>{count}</div>
        <div>
          <button onClick={() => setCount(count + 1)}>+</button>
          <button onClick={() => setCount(count - 1)}>-</button>
        </div>
        <h3>useReducer</h3>
        <div>{state.count}</div>
        <div>
          <button onClick={() => dispatch({ type: 'increment' })}>+</button>
          <button onClick={() => dispatch({ type: 'decrement' })}>-</button>
        </div>
        <h4 style={{ color: 'purple' }}>
          通过计数器案例：可以得出使用useReducer更新简单数据类型的值，实在是太繁琐了。还是使用useState方便
        </h4>
      </div>
      <h2>购物车案例：</h2>
      <table cellSpacing={0} border={1} width={800}>
        <thead>
          <tr>
            <th>商品名称</th>
            <th>商品价格</th>
            <th>商品数量</th>
            <th>总价</th>
            <th>操作</th>
          </tr>
        </thead>
        <tbody>
          {data.map((item) => {
            return (
              <tr key={item.id}>
                <td align="center">
                  {item.isEdit ? (
                    <input
                      value={item.name}
                      onChange={(e) => dispatchData({ type: 'UPDATE_NAME', id: item.id, newName: e.target.value })}
                      onBlur={() => dispatchData({ type: 'BLUR', id: item.id })}
                    />
                  ) : (
                    item.name
                  )}
                </td>
                <td align="center">{item.price}</td>
                <td align="center">
                  <button onClick={() => dispatchData({ type: 'DECREMENT', id: item.id })}>-</button>
                  {item.count}
                  <button onClick={() => dispatchData({ type: 'INCREMENT', id: item.id })}>+</button>
                </td>
                <td align="center">{item.price * item.count}</td>
                <td align="center">
                  <button onClick={() => dispatchData({ type: 'EDIT', id: item.id })}>编辑</button>
                  <button onClick={() => dispatchData({ type: 'DELETE', id: item.id })}>删除</button>
                </td>
              </tr>
            );
          })}
        </tbody>
        <tfoot>
          <tr>
            <td colSpan={4}></td>
            <td>总价：{data.reduce((prev, next) => prev + next.price * next.count, 0)}</td>
          </tr>
        </tfoot>
      </table>
    </>
  );
}

export default App;
